#include "iena_lib.h"
#include "iena_parser.h"  // 包含解析器头文件
#include <stdio.h>

/* 模拟的时间戳获取函数 */
uint64_t get_system_timestamp(void) {
    static uint64_t mock_timestamp = 123456789000ULL;
    return mock_timestamp++;
}

/* 模拟的状态获取函数 */
uint8_t get_system_status(void) {
    return 0x00; // 所有状态正常
}

/* 简单的字符串长度函数 */
static size_t simple_strlen(const char *str) {
    size_t len = 0;
    while (str[len]) len++;
    return len;
}
static inline uint16_t read_u16_be(const uint8_t *buffer) {
    return ((uint16_t)buffer[0] << 8) | buffer[1];
}
/* 添加大端序读取32位值的辅助函数 */
static inline uint32_t read_u32_be(const uint8_t *buffer) {
    return ((uint32_t)buffer[0] << 24) |
           ((uint32_t)buffer[1] << 16) |
           ((uint32_t)buffer[2] << 8)  |
           ((uint32_t)buffer[3]);
}
/* ==================== 封包测试函数 ==================== */

uint16_t test_pack_p_type(uint8_t *buffer, size_t buffer_size) {
    printf("【封包测试 - P型包】\n");

    iena_builder_t builder;
    iena_key_config_t p_config = {
            .key_id = 1,
            .packet_type = IENA_TYPE_P,
            .word_length = IENA_WORDLEN_1,
            .max_data_size = 200,
            .param_count = 4,
            .seq_num = 0
    };

    if (iena_builder_init(&builder, buffer, buffer_size, &p_config) == 0) {
        if (iena_begin_packet(&builder, get_system_timestamp, get_system_status) == 0) {
            uint16_t sensor_data[4] = {1000, 2000, 3000, 4000};
            iena_add_p_params(&builder, sensor_data, 4);
            uint16_t size = iena_finalize_packet(&builder);

            printf("构建的P型包大小: %u 字节\n", size);
            iena_print_packet_table(buffer, size);
            return size;
        }
    }
    return 0;
}

uint16_t test_pack_m_type(uint8_t *buffer, size_t buffer_size) {
    printf("【封包测试 - M型包】\n");

    iena_builder_t builder;
    iena_key_config_t m_config = {
            .key_id = 101,
            .packet_type = IENA_TYPE_M,
            .word_length = 0,
            .max_data_size = 400,
            .param_count = 0,
            .seq_num = 5
    };

    if (iena_builder_init(&builder, buffer, buffer_size, &m_config) == 0) {
        if (iena_begin_packet(&builder, get_system_timestamp, get_system_status) == 0) {
            const char *msg1 = "Hello IENA Protocol";
            const char *msg2 = "System Status OK";
            uint8_t binary_data[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22};

            iena_add_m_param(&builder, 0x1001, 100, msg1, simple_strlen(msg1));
            iena_add_m_param(&builder, 0x1002, 250, msg2, simple_strlen(msg2));
            iena_add_m_param(&builder, 0x1003, 500, binary_data, sizeof(binary_data));

            uint16_t size = iena_finalize_packet(&builder);

            printf("构建的M型包大小: %u 字节\n", size);
            iena_print_packet_table(buffer, size);
            return size;
        }
    }
    return 0;
}

uint16_t test_pack_n_type(uint8_t *buffer, size_t buffer_size) {
    printf("【封包测试 - N型包】\n");

    iena_builder_t builder;
    iena_key_config_t n_config = {
            .key_id = 201,
            .packet_type = IENA_TYPE_N,
            .word_length = IENA_WORDLEN_2,
            .max_data_size = 100,
            .param_count = 0,
            .seq_num = 10
    };

    if (iena_builder_init(&builder, buffer, buffer_size, &n_config) == 0) {
        if (iena_begin_packet(&builder, get_system_timestamp, get_system_status) == 0) {
            // 修改这里：使用16位字数组，按大端序排列
            uint16_t status1[2] = {0x1234, 0x5678};  // 0x12345678
            uint16_t status2[2] = {0xABCD, 0xEF00};  // 0xABCDEF00
            uint16_t status3[2] = {0x55AA, 0x55AA};  // 0x55AA55AA

            iena_add_n_param(&builder, 0x2001, status1);  // 传递数组
            iena_add_n_param(&builder, 0x2002, status2);
            iena_add_n_param(&builder, 0x2003, status3);

            uint16_t size = iena_finalize_packet(&builder);

            printf("构建的N型包大小: %u 字节\n", size);
            iena_print_packet_table(buffer, size);
            return size;
        }
    }
    return 0;
}

uint16_t test_pack_d_type(uint8_t *buffer, size_t buffer_size) {
    printf("【封包测试 - D型包】\n");

    iena_builder_t builder;
    iena_key_config_t d_config = {
            .key_id = 301,
            .packet_type = IENA_TYPE_D,
            .word_length = IENA_WORDLEN_1,
            .max_data_size = 150,
            .param_count = 0,
            .seq_num = 20
    };

    if (iena_builder_init(&builder, buffer, buffer_size, &d_config) == 0) {
        if (iena_begin_packet(&builder, get_system_timestamp, get_system_status) == 0) {
            uint16_t data1 = 0x1234;
            uint16_t data2 = 0x5678;
            uint16_t data3 = 0x9ABC;

            iena_add_d_param(&builder, 0x3001, 50, &data1);
            iena_add_d_param(&builder, 0x3002, 100, &data2);
            iena_add_d_param(&builder, 0x3003, 150, &data3);

            uint16_t size = iena_finalize_packet(&builder);

            printf("构建的D型包大小: %u 字节\n", size);
            iena_print_packet_table(buffer, size);
            return size;
        }
    }
    return 0;
}

/* ==================== 解析测试函数 ==================== */

void test_parse_p_type(const uint8_t *data, uint16_t size) {
    printf("\n【解析测试 - P型包】\n");

    iena_parsed_packet_t parsed;
    int result = iena_parse_packet(&parsed, data, size);

    if (result == 0 && parsed.is_valid) {
        printf("解析成功!\n");
        printf("包类型: %c型包\n", parsed.packet_type);
        printf("Key: %u, 序列号: %u, 参数个数: %u\n",
               parsed.iena_key, parsed.seq_num, parsed.param_count);

        printf("参数值:\n");
        for (int i = 0; i < parsed.param_count; i++) {
            printf("  参数[%d]: %u\n", i, IENA_GET_P_U16(&parsed, i));
        }

        // 验证数据正确性
        uint16_t expected[] = {1000, 2000, 3000, 4000};
        int all_correct = 1;
        for (int i = 0; i < 4; i++) {
            if (IENA_GET_P_U16(&parsed, i) != expected[i]) {
                all_correct = 0;
                break;
            }
        }
        printf("数据验证: %s\n", all_correct ? "通过" : "失败");
    } else {
        printf("解析失败，错误码: %d\n", result);
    }
}

void test_parse_m_type(const uint8_t *data, uint16_t size) {
    printf("\n【解析测试 - M型包】\n");

    iena_parsed_packet_t parsed;
    int result = iena_parse_packet(&parsed, data, size);

    if (result == 0 && parsed.is_valid) {
        printf("解析成功!\n");
        printf("包类型: %c型包\n", parsed.packet_type);
        printf("Key: %u, 序列号: %u, 参数个数: %u\n",
               parsed.iena_key, parsed.seq_num, parsed.param_count);

        printf("参数内容:\n");
        for (int i = 0; i < parsed.param_count; i++) {
            uint16_t id = IENA_GET_PARAM_ID(&parsed, i);
            uint16_t offset = IENA_GET_PARAM_OFFSET(&parsed, i);
            uint16_t length = IENA_GET_PARAM_LENGTH(&parsed, i);
            const uint8_t *param_data = IENA_GET_PARAM_DATA(&parsed, i);

            printf("  参数[%d]: ID=0x%04X, Offset=%u, Length=%u\n", i, id, offset, length);

            // 尝试显示文本内容
            printf("    数据: ");
            int is_text = 1;
            for (int j = 0; j < length; j++) {
                if (param_data[j] < 32 || param_data[j] > 126) {
                    is_text = 0;
                    break;
                }
            }

            if (is_text && length > 0) {
                printf("\"");
                for (int j = 0; j < length; j++) {
                    printf("%c", param_data[j]);
                }
                printf("\"\n");
            } else {
                for (int j = 0; j < length && j < 16; j++) {
                    printf("%02X ", param_data[j]);
                }
                if (length > 16) printf("...");
                printf("\n");
            }
        }
    } else {
        printf("解析失败，错误码: %d\n", result);
    }
}

void test_parse_n_type(const uint8_t *data, uint16_t size) {
    printf("\n【解析测试 - N型包】\n");

    iena_parsed_packet_t parsed;
    int result = iena_parse_packet(&parsed, data, size);

    if (result == 0 && parsed.is_valid) {
        printf("解析成功!\n");
        printf("包类型: %c型包\n", parsed.packet_type);
        printf("Key: %u, 序列号: %u, 参数个数: %u\n",
               parsed.iena_key, parsed.seq_num, parsed.param_count);

        printf("参数内容:\n");
        for (int i = 0; i < parsed.param_count; i++) {
            uint16_t id = IENA_GET_PARAM_ID(&parsed, i);
            uint16_t length = IENA_GET_PARAM_LENGTH(&parsed, i);
            const uint8_t *param_data = IENA_GET_PARAM_DATA(&parsed, i);

            printf("  参数[%d]: ID=0x%04X, Length=%u字节\n", i, id, length);

            // 修改这里：使用新的read_u32_be函数
            if (length == 4) {
                uint32_t value = read_u32_be(param_data);  // 改变的地方
                printf("    数值: 0x%08X (%u)\n", value, value);
            } else if (length == 2) {
                uint16_t value = read_u16_be(param_data);  // 改变的地方
                printf("    数值: 0x%04X (%u)\n", value, value);
            } else {
                printf("    数据: ");
                for (int j = 0; j < length; j++) {
                    printf("%02X ", param_data[j]);
                }
                printf("\n");
            }
        }

        // 验证数据正确性
        if (parsed.param_count >= 3) {
            printf("数据验证:\n");

            const uint8_t *data0 = IENA_GET_PARAM_DATA(&parsed, 0);
            const uint8_t *data1 = IENA_GET_PARAM_DATA(&parsed, 1);
            const uint8_t *data2 = IENA_GET_PARAM_DATA(&parsed, 2);

            uint32_t val0 = read_u32_be(data0);  // 改变的地方
            uint32_t val1 = read_u32_be(data1);  // 改变的地方
            uint32_t val2 = read_u32_be(data2);  // 改变的地方

            printf("  参数ID验证: %s\n",
                   (IENA_GET_PARAM_ID(&parsed, 0) == 0x2001 &&
                    IENA_GET_PARAM_ID(&parsed, 1) == 0x2002 &&
                    IENA_GET_PARAM_ID(&parsed, 2) == 0x2003) ? "通过" : "失败");

            printf("  参数0x2001值0x%08X (期望0x12345678): %s\n", val0,
                   (val0 == 0x12345678) ? "通过" : "失败");
            printf("  参数0x2002值0x%08X (期望0xABCDEF00): %s\n", val1,
                   (val1 == 0xABCDEF00) ? "通过" : "失败");
            printf("  参数0x2003值0x%08X (期望0x55AA55AA): %s\n", val2,
                   (val2 == 0x55AA55AA) ? "通过" : "失败");
        }
    } else {
        printf("解析失败，错误码: %d\n", result);
    }
}

void test_parse_d_type(const uint8_t *data, uint16_t size) {
    printf("\n【解析测试 - D型包】\n");

    iena_parsed_packet_t parsed;
    int result = iena_parse_packet(&parsed, data, size);

    if (result == 0 && parsed.is_valid) {
        printf("解析成功!\n");
        printf("包类型: %c型包\n", parsed.packet_type);
        printf("Key: %u, 序列号: %u, 参数个数: %u\n",
               parsed.iena_key, parsed.seq_num, parsed.param_count);

        printf("参数内容:\n");
        for (int i = 0; i < parsed.param_count; i++) {
            uint16_t id = IENA_GET_PARAM_ID(&parsed, i);
            uint16_t delay = IENA_GET_PARAM_OFFSET(&parsed, i); // offset字段存储delay
            uint16_t length = IENA_GET_PARAM_LENGTH(&parsed, i);
            const uint8_t *param_data = IENA_GET_PARAM_DATA(&parsed, i);

            printf("  参数[%d]: ID=0x%04X, Delay=%u微秒, Length=%u字节\n",
                   i, id, delay, length);

            // 修正：使用正确的大端序解析
            if (length == 2) {
                uint16_t value = read_u16_be(param_data);
                printf("    数值: 0x%04X (%u)\n", value, value);
            } else if (length == 4) {
                uint32_t value = read_u32_be(param_data);
                printf("    数值: 0x%08X (%u)\n", value, value);
            } else {
                printf("    数据: ");
                for (int j = 0; j < length; j++) {
                    printf("%02X ", param_data[j]);
                }
                printf("\n");
            }
        }

        // 添加数值验证
        if (parsed.param_count >= 3) {
            printf("数据验证:\n");
            const uint8_t *data0 = IENA_GET_PARAM_DATA(&parsed, 0);
            const uint8_t *data1 = IENA_GET_PARAM_DATA(&parsed, 1);
            const uint8_t *data2 = IENA_GET_PARAM_DATA(&parsed, 2);

            uint16_t val0 = read_u16_be(data0);
            uint16_t val1 = read_u16_be(data1);
            uint16_t val2 = read_u16_be(data2);

            printf("  参数0x3001值0x%04X (期望0x1234): %s\n", val0,
                   (val0 == 0x1234) ? "通过" : "失败");
            printf("  参数0x3002值0x%04X (期望0x5678): %s\n", val1,
                   (val1 == 0x5678) ? "通过" : "失败");
            printf("  参数0x3003值0x%04X (期望0x9ABC): %s\n", val2,
                   (val2 == 0x9ABC) ? "通过" : "失败");
        }
    } else {
        printf("解析失败，错误码: %d\n", result);
    }
}

/* ==================== 主测试函数 ==================== */

int main(void) {
    printf("IENA协议完整测试 - 封包与解析\n");
    printf("=============================\n\n");

    uint8_t packet_buffer[512];
    uint16_t packet_size;

    // 测试P型包
    packet_size = test_pack_p_type(packet_buffer, sizeof(packet_buffer));
    if (packet_size > 0) {
        test_parse_p_type(packet_buffer, packet_size);
    }

    printf("\n===========================================================================================================\n");

    // 测试M型包
    packet_size = test_pack_m_type(packet_buffer, sizeof(packet_buffer));
    if (packet_size > 0) {
        test_parse_m_type(packet_buffer, packet_size);
    }

    printf("\n===========================================================================================================\n");

    // 测试N型包
    packet_size = test_pack_n_type(packet_buffer, sizeof(packet_buffer));
    if (packet_size > 0) {
        test_parse_n_type(packet_buffer, packet_size);
    }

    printf("\n===========================================================================================================\n");

    // 测试D型包
    packet_size = test_pack_d_type(packet_buffer, sizeof(packet_buffer));
    if (packet_size > 0) {
        test_parse_d_type(packet_buffer, packet_size);
    }


    return 0;
}